package com.xinqi.modules.user.users.user.controller.app;

import cn.dev33.satoken.stp.StpUtil;
import com.xinqi.common.core.utils.MessageUtils;
import com.xinqi.common.log.asynclog.annotation.AsyncLog;
import com.xinqi.common.log.asynclog.enums.AsyncOperaType;
import com.xinqi.common.log.asynclog.enums.AsyncType;
import com.xinqi.common.satoken.utils.LoginHelper;
import com.xinqi.modules.user.user.dto.req.*;
import com.xinqi.modules.user.user.dto.req.v2.UpdatePhoneV2Dto;
import com.xinqi.modules.user.user.dto.rsp.UserResultDTO;
import com.xinqi.common.base.response.PageInfo;
import com.xinqi.common.base.response.R;
import com.xinqi.modules.user.users.user.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 用户信息APP控制层
 *
 * @author: wenjie
 * @date: 2023/05/17
 */
@Tag(name = "App-用户信息", description = "用户信息App接口")
@RestController
@RequestMapping("/app/user")
@RequiredArgsConstructor
public class UserAppController {
    private final UserService userService;

    /**
     * 用户信息-分页
     */
    @Operation(summary = "用户信息-分页")
    @GetMapping("/page")
    public R<PageInfo<UserResultDTO>> page(@ParameterObject UserQueryDTO dto) {
        PageInfo<UserResultDTO> page = userService.page(dto, dto);
        return R.data(page);
    }

    @Operation(summary = "用户信息-列表")
    @GetMapping("/list")
    public R<List<UserResultDTO>> list(@ParameterObject UserQueryDTO dto) {
        List<UserResultDTO> list = userService.list(dto);
        return R.data(list);
    }

    /**
     * 根据userId获取用户信息
     *
     * @param userId
     * @return
     */
    @GetMapping("/get/{userId}")
    public R<UserResultDTO> getInfo(@PathVariable("userId") Long userId) {
        return R.ok(userService.selectById(userId));
    }

    /**
     * 获取登录人的用户信息
     *
     * @return
     */
    @GetMapping("/getInfo")
    public R<UserResultDTO> getInfo() {
        return R.ok(userService.selectById(LoginHelper.getUserId()));
    }

    @AsyncLog(title = "用户修改个人信息", asyncType = AsyncType.USER_INFO, operatorType = AsyncOperaType.USER_INFO)
    @PostMapping("/updateUserInfo")
    public R<String> updateUserInfo(@Validated @RequestBody UpdateUserDto dto) {
        dto.setUserId(LoginHelper.getUserId());
        userService.updateUserInfo(dto);
        return R.ok(MessageUtils.message("sys.user.info.update.success"));
    }

    @AsyncLog(title = "用户修改新奇号", asyncType = AsyncType.USER_INFO, operatorType = AsyncOperaType.USER_INFO)
    @GetMapping("/updateXinqi/{xinqiNumber}")
    public R<String> updateXinqiNumber(@PathVariable("xinqiNumber") String xinqiNumber) {
        userService.updateXinqiNumber(xinqiNumber, LoginHelper.getUserId());
        return R.ok(MessageUtils.message("sys.user.xinqiNumber.update.success"));
    }

    @AsyncLog(title = "用户修改隐私设置", asyncType = AsyncType.USER_INFO, operatorType = AsyncOperaType.USER_INFO)
    @PostMapping("setPrivacy")
    public R<String> setPrivacy(@Validated @RequestBody SetPrivacyDto dto) {
        dto.setUserId(LoginHelper.getUserId());
        userService.updatePrivacy(dto);
        return R.ok(MessageUtils.message("sys.user.update.success"));
    }

    @AsyncLog(title = "用户更换手机号", asyncType = AsyncType.USER_INFO, operatorType = AsyncOperaType.USER_INFO)
    @PostMapping("updatePhone")
    public R<String> updatePhone(@Validated @RequestBody UpdatePhoneDto dto) {
        dto.setUserId(LoginHelper.getUserId());
        userService.updatePhone(dto);
        return R.ok(MessageUtils.message("sys.user.mobile.update.success"));
    }

    /**
     * 用户更换手机号-加密码校验
     * @author dzy
     */
    @AsyncLog(title = "用户更换手机号", asyncType = AsyncType.USER_INFO, operatorType = AsyncOperaType.USER_INFO)
    @PostMapping("updatePhone/v2")
    public R<String> updatePhoneV2(@Validated @RequestBody UpdatePhoneV2Dto dto) {
        dto.setUserId(LoginHelper.getUserId());
        userService.updatePhoneV2(dto);
        return R.ok(MessageUtils.message("sys.user.mobile.update.success"));
    }

    @AsyncLog(title = "用户绑定邮箱", asyncType = AsyncType.USER_INFO, operatorType = AsyncOperaType.USER_INFO)
    @PostMapping("bindEmail")
    public R<String> bindEmail(@Validated @RequestBody UpdateEmailDto dto) {
        dto.setUserId(LoginHelper.getUserId());
        userService.bindEmail(dto);
        return R.ok(MessageUtils.message("sys.user.email.bind.success"));
    }

    @AsyncLog(title = "用户解绑邮箱", asyncType = AsyncType.USER_INFO, operatorType = AsyncOperaType.USER_INFO)
    @PostMapping("unbindEmail")
    public R<String> unbindEmail(@Validated @RequestBody UpdateEmailDto dto) {
        dto.setUserId(LoginHelper.getUserId());
        userService.unbindEmail(dto);
        return R.ok(MessageUtils.message("sys.user.email.unbind.success"));
    }

    @AsyncLog(title = "用户修改密码", asyncType = AsyncType.USER_INFO, operatorType = AsyncOperaType.USER_INFO)
    @PostMapping("changePassword")
    public R<String> changePassword(@Validated @RequestBody PasswordChangeDto dto) {
        Long userId = LoginHelper.getUserId();
        dto.setUserId(userId);
        userService.resetUserPwd(dto);
        StpUtil.logout(userId);
        return R.ok(MessageUtils.message("sys.user.password.update.success"));
    }

    @AsyncLog(title = "用户忘记密码", asyncType = AsyncType.USER_INFO, operatorType = AsyncOperaType.USER_INFO)
    @PostMapping("/forgotPassword")
    public R<String> forgotPassword(@Validated @RequestBody ForgotChangeDto dto) {
        Long userId = LoginHelper.getUserId();
        dto.setUserId(userId);
        userService.forgotPassword(dto);
        StpUtil.logout(userId);
        return R.ok(MessageUtils.message("sys.user.password.update.success"));
    }

    @AsyncLog(title = "用户身份认证", asyncType = AsyncType.USER_INFO, operatorType = AsyncOperaType.USER_INFO)
    @PostMapping("authentication")
    public R<String> authentication(@Validated @RequestBody UserAuthenticationDto dto) throws Exception {
        dto.setUserId(LoginHelper.getUserId());
        userService.authentication(dto);
        return R.ok(MessageUtils.message("sys.user.authentication.success"));
    }

    @AsyncLog(title = "用户账号注销", asyncType = AsyncType.USER_INFO, operatorType = AsyncOperaType.USER_INFO)
    @PostMapping("accountCancel")
    public R<String> accountCancel() {
        userService.accountCancel(LoginHelper.getUserId());
        return R.ok(MessageUtils.message("sys.user.accountcancel.success"));
    }

}
